

package org.platform.lwc.log.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.platform.lwc.log.annotation.ApiLog;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.util.Arrays;

/**
 *  方法级别注解
 *
 * @author lwc
 * @date 2020/12/28
 */
@Slf4j
@Aspect
public class ApiLogAspect {



	/**
	 * 获取方法中声明的注解
	 *
	 * @param joinPoint
	 * @return
	 * @throws NoSuchMethodException
	 */
	public ApiLog getDeclaredAnnotation(ProceedingJoinPoint joinPoint) throws NoSuchMethodException {
		// 获取方法名
		String methodName = joinPoint.getSignature().getName();
		// 反射获取目标类
		Class<?> targetClass = joinPoint.getTarget().getClass();
		// 拿到方法对应的参数类型
		Class<?>[] parameterTypes = ((MethodSignature) joinPoint.getSignature()).getParameterTypes();
		// 根据类、方法、参数类型（重载）获取到方法的具体信息
		Method objMethod = targetClass.getMethod(methodName, parameterTypes);
		// 拿到方法定义的注解信息
		ApiLog annotation = objMethod.getDeclaredAnnotation(ApiLog.class);
		// 返回
		return annotation;
	}

	@Around("@annotation(apiLog)")
	public Object around(ProceedingJoinPoint joinPoint, ApiLog apiLog) throws Throwable {

		// 获取方法传入参数
		ApiLog lwc = getDeclaredAnnotation(joinPoint);
		// 接收到请求，记录请求内容
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
		HttpServletRequest request = attributes.getRequest();
		log.info("AROUND START LOGGER");
		log.info("DESCRIPTION : " + lwc.value());
		log.info("URL : " + request.getRequestURL().toString());
		log.info("HTTP_METHOD : " + request.getMethod());
		log.info("IP : " + request.getRemoteAddr());
		log.info("CLASS_METHOD : " + joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName());
		log.info("ARGS : " + Arrays.toString(joinPoint.getArgs()));
		// 执行源方法
		Object proceed = joinPoint.proceed();
		log.info("AROUND END LOGGER");
		return proceed;
	}
}